package me.zhengjie.config.webConfig;

/**
 * @author Yaco
 * @title: MonitorDataFilter
 */

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

@Slf4j
@Component
@WebFilter(urlPatterns = "/*", filterName = "monitorDataFilter")
public class MonitorDataFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String uri = httpServletRequest.getRequestURI();
        String contentType = httpServletRequest.getHeader("content-type");
        boolean printPostFlag = true;
//        log.info(" ### contentType = {}", contentType);
        // 表单post提交不打印body
        if (StrUtil.isNotBlank(contentType) && contentType.equalsIgnoreCase("application/x-www-form-urlencoded")) {
            printPostFlag = false;
        }
        if (!isStatic(uri)) {
            printRequest(httpServletRequest);
        }
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest, printPostFlag);

        if (!isStatic(uri)) {
            //打印请求内容
            String method = httpServletRequest.getMethod();
            //delete 和put 请求暂时未处理
            log.info("Request Parameters:");
            printParams(httpServletRequest);
            if ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) {
                if (printPostFlag) {
                    String requestBody = requestWrapper.getBody();
                    boolean reqTypeJSON = JSONUtil.isTypeJSON(requestBody);
                    if (reqTypeJSON) {
                        log.info("===>> Post Body: \n {}", JSONUtil.toJsonPrettyStr(requestBody));
                    } else {
                        log.info("===>> Post Body: {}", requestBody);
                    }
                }
            }
        }
        ResponseWrapper responseWrapper = new ResponseWrapper(httpServletResponse);
        filterChain.doFilter(requestWrapper, responseWrapper);
        //打印响应内容
        byte[] bytes = responseWrapper.getBytes();
        String val = new String(bytes, "UTF-8");
        if (!isStatic(uri)) {
//            boolean rspTypeJSON = JSONUtil.isTypeJSON(val);
//            if (rspTypeJSON) {
//                log.info("<<=== Response: \n {}", JSONUtil.toJsonPrettyStr(val));
//            } else {
//                log.info("<<=== Response: {}", val);
//            }
            log.info("<<=== Response: {}", val);
        }
        //将数据 再写到 response 中
        servletResponse.getOutputStream().write(bytes);
        servletResponse.getOutputStream().flush();
        servletResponse.getOutputStream().close();
    }

    @Override
    public void destroy() {
        log.debug(" HttpServletRequest destroy...");
    }

    private void printRequest(HttpServletRequest request) {
        log.info("===>> Begin to execute:" + request.getServletPath());// 得到请求URL地址时使用的方法
        log.info("===>> request Method:" + request.getMethod());
//        getIpAddr(request);
        log.debug("===>> request getRequestURL:" + request.getRequestURL());// 得到请求的URL地址
        log.debug("===>> request getRequestURI:" + request.getRequestURI());// 得到请求的资源
        log.debug("===>> request getQueryString :" + request.getQueryString());// 得到请求的URL地址中附带的参数
        log.debug("===>> request getPathInfo:" + request.getPathInfo());
        log.debug("===>> request getRemoteAddr:" + request.getRemoteAddr());// 得到来访者的IP地址
        log.debug("===>> request getRemoteHost:" + request.getRemoteHost());
        log.debug("===>> request getRemotePort:" + request.getRemotePort());
        log.debug("===>> request getLocalAddr:" + request.getLocalAddr());// 获取WEB服务器的IP地址
        log.debug("===>> request getLocalName:" + request.getLocalName());// 获取WEB服务器的主机名
        log.debug("===>> request getRemoteUser:" + request.getRemoteUser());// 获取WEB服务器的主机名
        log.debug("===>> request Header:" + request.getRemoteUser());// 获取WEB服务器的主机名
        Enumeration<String> reqHeadInfos = request.getHeaderNames();// 获取所有的请求头
        while (reqHeadInfos.hasMoreElements()) {
            String headName = (String) reqHeadInfos.nextElement();
            String headValue = request.getHeader(headName);// 根据请求头的名字获取对应的请求头的值
            log.debug("======>>>> request Header[" + headName + "]:" + headValue);
        }
    }

    private void printParams(HttpServletRequest request) {
        String params = "";
        for (Map.Entry<String, String[]> entry : ((Map<String, String[]>) request.getParameterMap()).entrySet()) {
            for (String str : entry.getValue()) {
                if (isPwd(entry.getKey())) {
                    log.info(" =================>> [" + entry.getKey() + "] : ******");
                } else {
                    log.info(" =================>> [" + entry.getKey() + "] : " + str);
                }
                if ("GET".equals(request.getMethod()) && !"locale".equals(entry.getKey())) {
                    params += entry.getKey() + "=" + str + "&";
                }
            }
        }
        request.setAttribute("params", params);
    }

    /**
     * 获取当前网络ip
     */
//    public void getIpAddr(HttpServletRequest request) {
//        String ipAddress = request.getHeader("x-forwarded-for");
//        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
//            ipAddress = request.getHeader("Proxy-Client-IP");
//        }
//        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
//            ipAddress = request.getHeader("WL-Proxy-Client-IP");
//        }
//        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
//            ipAddress = request.getRemoteAddr();
//            if ("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)) {
//                // 根据网卡取本机配置的IP
//                InetAddress inet = null;
//                try {
//                    inet = InetAddress.getLocalHost();
//                } catch (UnknownHostException e) {
//                    e.printStackTrace();
//                }
//                ipAddress = inet.getHostAddress();
//            }
//        }
//        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
//        if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() = 15
//            if (ipAddress.indexOf(",") > 0) {
//                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
//            }
//        }
//        log.info("===>> request IP:" + ipAddress);
//    }
    private boolean isPwd(String str) {
        return str.contains("pwd") || str.contains("Pwd") || str.contains("password") || str.contains("passWord");
    }

    private boolean isStatic(String uri) {
        if ((StrUtil.endWithIgnoreCase(uri, "css") || StrUtil.endWithIgnoreCase(uri, ".js") || StrUtil.endWithIgnoreCase(uri, ".css") || StrUtil.endWithIgnoreCase(uri, ".png") || StrUtil.endWithIgnoreCase(uri, ".jpg") || StrUtil.endWithIgnoreCase(uri, ".jpeg")) || (StrUtil.startWithIgnoreCase(uri, "/webjars/springfox-swagger-ui/"))) {
            return true;
        }
        return false;
    }
}

